package components

import (
	"encoding/json"
	"github.com/astaxie/beego"
	"github.com/gaoyue1989/sshexec"
	"library/common"
	"library/ssh"
	"models"
	"time"
	"strings"
	"fmt"
	"library/p2p/init_sever"
)


type FileBaseComponents struct {
	name    string
	file   *models.GjFileTask
}

func (c *FileBaseComponents) SetFileTask(file *models.GjFileTask) {
	c.file = file
}


func (c *FileBaseComponents) GetFileName (file string) []string {
	filesname := []string{}
	files := strings.Split(file, "\n")
	for _, f := range files {
		if !common.InList(string(f), filesname) {
			filesname = append(filesname,  string(f))
		}
	}
	return filesname
}
/**
* 执行远端传输文件
 */
func (c *FileBaseComponents) CopyFilesBySftp(src string, dest string, hosts []string) ([]sshexec.ExecResult, error) {
	beego.Info(c.file)
	id := c.SaveRecord("Transfer" +c.file.Files +"from" +c.file.SourceIpHosts +"to"+c.file.TargetIpHosts)
	start := time.Now()
	createdAt := int(start.Unix())
	sshExecAgent := sshexec.SSHExecAgent{}
	sshExecAgent.Worker = SSHWorker
	sshExecAgent.TimeOut = time.Duration(SSHREMOTETIMEOUT) * time.Second
	s, err := sshExecAgent.SftpHostByKey(hosts, c.file.TargetAccount, src, dest)
	//获取执行时间
	duration := common.GetInt(time.Now().Sub(start).Seconds())
	status := 1
	if err != nil {
		status = 0
	}
	c.SaveRecordRes(id, duration, createdAt, status, s)
	return s, err

}
/**
* 执行远端传输文件 p2p方式
 */
func (c *FileBaseComponents) CopyFilesByP2p(id string, src string, dest string, hosts []string) ([]sshexec.ExecResult, error) {
	start := time.Now()
	rid := c.SaveRecord("Transfer by p2p"+c.file.Files +"from" +c.file.SourceIpHosts+"to"+c.file.TargetIpHosts)
	createdAt := int(start.Unix())
	s, err := gopubssh.TransferByP2p(id, hosts, c.file.TargetAccount, src, dest, SSHREMOTETIMEOUT)
	//获取执行时间
	duration := common.GetInt(time.Now().Sub(start).Seconds())

	status := 1
	if err != nil {
		status = 0
	}
	c.SaveRecordRes(rid, duration, createdAt, status, s)
	return s, err
}


func (c *FileBaseComponents) SaveRecord(command string) int {
	re := models.GjFileRecord{}
	re.Command = command
	if c.file == nil || c.file.Id == 0 {
		re.TaskId = -99
	} else {
		re.TaskId = c.file.Id
	}
	re.Status = 1
	id, err := models.AddGjFileRecord(&re)
	if err != nil {
		beego.Error(err)
	}
	beego.Info("id:", id)
	return int(id)
}

func (c *FileBaseComponents) SaveRecordRes(id int, duration int, createdAt int, status int, value interface{}) {
	beego.Info(value)
	if duration < 0 {
		duration = 0
	}
	beego.Info("id1:", id)
	re, err := models.GetGjFileRecordById(id)
	if err != nil {
		beego.Error(err)
		return
	}
	re.IsFinal = 1
	re.Duration = duration
	sResult, _ := json.Marshal(value)
	re.CreatedAt = createdAt
	re.Memo = string(sResult)
	re.Status = int16(status)
	err = models.UpdateGjFileRecordById(re)
	if err != nil {
		beego.Error(err)
	}
}

/**
* 执行远端目标机命令
 */
func (c *FileBaseComponents) runRemoteCommand(command string, hosts []string) ([]sshexec.ExecResult, error) {
	id := c.SaveRecord(command)
	start := time.Now()
	createdAt := int(start.Unix())
	sshExecAgent := sshexec.SSHExecAgent{}
	sshExecAgent.Worker = SSHWorker
	sshExecAgent.TimeOut = time.Duration(SSHREMOTETIMEOUT) * time.Second
	s, err := sshExecAgent.SshHostByKey(hosts, c.file.TargetAccount, command)
	//获取执行时间
	duration := common.GetInt(time.Now().Sub(start).Seconds())

	status := 1
	if err != nil {
		status = 0
	}
	c.SaveRecordRes(id, duration, createdAt, status, s)
	return s, err
}

/**
 * 发送p2p客户端并启动
 *
 */
func (c *FileBaseComponents) SendP2pAgent(dirAgentPath string, destPath string ,hosts []string) error {
	agentFile := "agent_main"
	cmds2 := []string{}
	cmds2 = append(cmds2, fmt.Sprintf("ps -ef |grep %s| grep -v grep  |awk '{print $2}' |xargs kill -9", agentFile))
	cmd2 := strings.Join(cmds2, " && ")
	c.runRemoteCommand(cmd2, hosts)

	cmds1 := []string{}
	cmds1 = append(cmds1, fmt.Sprintf("mkdir -p  %s", strings.TrimRight(destPath, "/")+"/src"))
	cmds1 = append(cmds1, fmt.Sprintf("rm -rf   %s/src/%s", strings.TrimRight(destPath, "/"), agentFile))
	cmd1 := strings.Join(cmds1, "&&")
	_, err := c.runRemoteCommand(cmd1, hosts)
	if err != nil {
		return err
	}
	_, err = c.CopyFilesBySftp(strings.TrimRight(dirAgentPath, "/")+"/"+agentFile, strings.TrimRight(destPath, "/")+"/src/"+agentFile, hosts)
	if err != nil {
		return err
	}
	agentFileConf := "agent.json"
	_, err = c.CopyFilesBySftp(strings.TrimRight(dirAgentPath, "/")+"/"+agentFileConf, strings.TrimRight(destPath, "/")+"/src/"+agentFileConf, hosts)
	if err != nil {
		return err
	}
	controlFile := "control"
	_, err = c.CopyFilesBySftp(strings.TrimRight(dirAgentPath, "/")+"/"+controlFile, strings.TrimRight(destPath, "/")+"/"+controlFile, hosts)
	if err != nil {
		return err
	}
	cmds := []string{}
	cmds = append(cmds, fmt.Sprintf("chmod 777 -R %s/* ", strings.TrimRight(destPath, "/")))
	cmds = append(cmds, fmt.Sprintf("cd %s/", strings.TrimRight(destPath, "/")))
	cmds = append(cmds, "./control start")
	cmd := strings.Join(cmds, "&&")
	_, err = c.runRemoteCommand(cmd, hosts)
	if err != nil {
		return err
	}
	init_sever.P2pSvc.CheckAllClientIp(hosts)
	return nil
}


func (c *FileBaseComponents) StartP2pAgent(ips []string, destPath string) error {
	cmds := []string{}
	cmds = append(cmds, fmt.Sprintf("cd %s/", strings.TrimRight(destPath, "/")))
	cmds = append(cmds, "./control start")
	cmd := strings.Join(cmds, "&&")
	_, err := c.runRemoteCommand(cmd, ips)
	return err
}